package ru.msu.phys.cmp.mpga.domain.bresenham;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Iterator;

import ru.msu.phys.cmp.mpga.domain.Point;

public class CanvasBresenhamTemplate extends Canvas {
    
	private static final long serialVersionUID = 4012295323526936729L;
    
    int centerX, centerY, PIXEL_SIZE;
    
    	// initialize the graphics
    void initgr() {
    
    	PIXEL_SIZE = 8;
    	centerX = PIXEL_SIZE * ((getWidth() / PIXEL_SIZE) / 2);
    	centerY = PIXEL_SIZE * ((getHeight() / PIXEL_SIZE) / 2);
    
    }
    	 
    	// draw one pixel with center (x, y)
   	void putPixel(Graphics g, int x, int y) {
		g.setColor(Color.GREEN);
		g.fillRect((x * PIXEL_SIZE) - (PIXEL_SIZE / 2), (y * PIXEL_SIZE)
		        - (PIXEL_SIZE / 2), PIXEL_SIZE, PIXEL_SIZE);
	}

   
	void drawBresenhamLine(Graphics g, int x1, int y1, int x2, int y2) {
		BresenhamObject pointLine = new BresenhamLine(x1,y1,x2,y2);
     	Iterator<Point> iterLine = pointLine.begin();
     	while (iterLine.hasNext()){
     		Point point = iterLine.next();
     		putPixel( g, point.getX(),point.getY());
     	}
     	
   		g.setColor(Color.black);
   		g.drawLine(x1 * PIXEL_SIZE, y1 * PIXEL_SIZE, x2 * PIXEL_SIZE, y2
   				 * PIXEL_SIZE);
   	}
   
   	void putSome(Graphics g, double x1, double y1) {
   		int x = (int)x1;
   		int y = (int)y1;
   
   		putPixel(g, x, y);
   		putPixel(g, -x, y);
   		putPixel(g, x, -y);
   		putPixel(g, -x, -y);
   	}
   	
   		
    void drawBresenhamEllipse(Graphics g, int a,int b) {
    	BresenhamObject pointEllipse = new BresenhamEllipse(a, b);
    	Iterator<Point> iterEllipse = pointEllipse.begin();
    	while (iterEllipse.hasNext()){
    		Point point = iterEllipse.next();
    		putSome( g, point.getX(),point.getY());
    	}
    	
    	g.setColor(Color.black);
	   	g.drawOval(-(a * PIXEL_SIZE), -(b * PIXEL_SIZE), 2 * a *
	   			PIXEL_SIZE, 2 * b * PIXEL_SIZE);
    }
   	
   	// override the canvas paint method
   	public void paint(Graphics g) {
   
   		initgr();
   
   		paintCoordinateSystem(g);
   
   		drawBresenhamLine(g, 0, 0, 5, 3);
   
   
   		drawBresenhamEllipse(g, 15, 10);
   	}
   
   	private void paintCoordinateSystem(Graphics g) {
   
   		g.setColor(Color.WHITE);
   		g.fillRect(0, 0, getWidth(), getHeight());
   
   		// coordinate grid
   		g.setColor(Color.BLACK);
   
   		for (int i = 0; i <= getWidth(); i += PIXEL_SIZE) {
   			g.drawLine(i, 0, i, getHeight());
   			g.drawLine(0, i, getWidth(), i);
   		}
   
   		g.setColor(Color.RED);
   		g.drawLine(centerX, 0, centerX, getHeight());
   		g.drawLine(0, centerY, getWidth(), centerY);
   		g.drawLine(centerX - 5, 10, centerX, 0);
   		g.drawLine(centerX + 5, 10, centerX, 0);
  		g.drawLine(getWidth() - 10, centerY - 5, getWidth(), centerY);
   		g.drawLine(getWidth() - 10, centerY + 5, getWidth(), centerY);
   		g.drawString("x", getWidth() - 20, centerY - 10);
   		g.drawString("y", centerX + 10, 20);
   		for (int i = -170; i <= 190; i += 10) {
   			g.drawLine(centerX - 4, centerY + i, centerX + 4, centerY + i);
   		}
   		for (int i = -240; i <= 220; i += 10) {
   			g.drawLine(centerX + i, centerY - 4, centerX + i, centerY + 4);
   		}
   
   		for (int i = -150; i <= 150; i += 50) {
   			g.drawLine(centerX - 10, centerY + i, centerX + 10, centerY + i);
   		}
   		for (int i = -200; i <= 200; i += 50) {
  			g.drawLine(centerX + i, centerY - 10, centerX + i, centerY + 10);
   		}
  		g.drawString("5", centerX - 25, centerY - 45);
   		g.drawString("5", centerX + 45, centerY - 15);
   
   		// translate origin and orientation
  		g.translate(centerX, centerY);
   		((Graphics2D) g).scale(1.0, -1.0);
   
  		// center
   		g.fillOval(-PIXEL_SIZE / 2, -PIXEL_SIZE / 2, PIXEL_SIZE, PIXEL_SIZE);
   
   	}
}